/**
 *
 * 逻辑实现
 * 1.根据MD5查找所有重复的图片资源字典，key=md5str:value=FPackageItemList
 * 2.分两种情况。当资源在公共包直接更新引用,删除其他的多余资源。
 * 当资源不再公共包,修改引用指向同一个资源，删除其他多余资源，再将这个引用的资源移动到公共包中去。
 *
 *
 *
 */
import { System, FairyEditor } from "csharp";
import { $generic } from "puerts";

const App = FairyEditor.App;
let StringList = $generic(System.Collections.Generic.List$1, System.String);
let FPackageItemList = $generic(
  System.Collections.Generic.List$1,
  FairyEditor.FPackageItem
);
let Dict = $generic(
  System.Collections.Generic.Dictionary$2,
  System.String,
  FPackageItemList
);

class ComPKgData {
  InComPKG: boolean; //是否存在Common包中
  PkGItem: FairyEditor.FPackageItem; //要放到Common包中的
  NotInComPKGItems: System.Collections.Generic.List$1<FairyEditor.FPackageItem>; //其他要
}

let allPicMd5Array: System.Collections.Generic.List$1<string> = new StringList();
let repeatPicDict: System.Collections.Generic.Dictionary$2<System.String, System.Collections.Generic.List$1<FairyEditor.FPackageItem>> = new Dict();
let commPkgName: string = "Common"; //公共包名字


export default class Utils {
  /**
   *
   * 查找图片计算MD5值
   */
  public static findAndCalMd5(): void {

    allPicMd5Array.Clear();
    repeatPicDict.Clear();

    let allPackages = App.project.allPackages;
    for (let index = 0; index < allPackages.Count; index++) {
      const everypackage = allPackages.get_Item(index);
      console.log("---------" + everypackage.name + "---------");
      let packItems = everypackage.items;
      for (let i = 0; i < packItems.Count; i++) {
        const packItem = packItems.get_Item(i);
        //收集重复图片Item
        if (packItem.type === "image") {
          let fileExist=System.IO.File.Exists(packItem.file);
          console.log('fileExist:'+fileExist);

          if(fileExist)
          {
            let md5str1 = FairyEditor.BuilderUtil.GetMD5HashFromFile(packItem.file);
            if (!allPicMd5Array.Contains(md5str1)) {
              allPicMd5Array.Add(md5str1);
              let repeatPicItemArray: System.Collections.Generic.List$1<FairyEditor.FPackageItem> =
                new FPackageItemList();
              repeatPicItemArray.Add(packItem);
              repeatPicDict[md5str1] = repeatPicItemArray;
            } else {
              let repeatPicItemArray: System.Collections.Generic.List$1<FairyEditor.FPackageItem> =
                repeatPicDict[md5str1];
              repeatPicItemArray.Add(packItem);
            }
          }

        }
      }
    }
  }

  /**
   *  显示重复图片信息，并处理重复资源
   *
   */
  public static showRepeatPicInfoAndDeal(): void {
    for (const key in repeatPicDict) {
      if (Object.prototype.hasOwnProperty.call(repeatPicDict, key)) {
        let repeatPicItemArray: System.Collections.Generic.List$1<FairyEditor.FPackageItem> =
          repeatPicDict[key];
        if (repeatPicItemArray.Count > 1) {
          console.log("repeatPicItemArray.Count:" + repeatPicItemArray.Count);
          let comPKgData: ComPKgData =
            Utils.FindPicItemExistCommonPackage(repeatPicItemArray);
          console.log(
            "公共包是否包含:" + comPKgData.InComPKG,
            "要移动到公共包资源:" + comPKgData.PkGItem.file,
            "重复资源数量:" + comPKgData.NotInComPKGItems.Count
          );
          if (comPKgData.InComPKG) {
            console.log("*********资源存在公共包中******");
            //Common包存在这个资源修改其他资源的引用,修改完后资源删除 comPKgData.PkGItem
            Utils.UpdatePicRefAndCleanRepeatPic(comPKgData);
          } else {
            //Common包不存在这个资源，要先移动到Common包Res下,再修改其他资源的引用,修改完后资源删除
            console.log("*********资源不存在公共包中******");
            //先指向同一个引用
            comPKgData.NotInComPKGItems.RemoveAt(0);
            Utils.UpdatePicRefAndCleanRepeatPic(comPKgData);
            //再将同一个引用资源移动到Common包中去
            let CommonPKG = Utils.GetPKGByName(commPkgName);
            if (CommonPKG != null) {
              let ComPKResItem: FairyEditor.FPackageItem = Utils.GetCommonPKGRes(CommonPKG);
              let ItemArray: System.Collections.Generic.List$1<FairyEditor.FPackageItem> =
                new FPackageItemList();
              ItemArray.Add(comPKgData.PkGItem);
              let libraryView: FairyEditor.View.LibraryView = null;
              if (libraryView == null) {
                libraryView = new FairyEditor.View.LibraryView();
              }
              libraryView.MoveResources(ComPKResItem, ItemArray);
            }
          }
          console.log("###########");
        }
      }
    }
  }


  /**
   *  根据comPKgData查找引用，替换引用,删除无用资源
   * @param comPKgData
   */
  public static UpdatePicRefAndCleanRepeatPic(comPKgData): void {

    for (let i = 0; i < comPKgData.NotInComPKGItems.Count; i++) {
      const element = comPKgData.NotInComPKGItems.get_Item(i);
      let dependencyQuery: FairyEditor.DependencyQuery = Utils.GetPicReferences(element.GetURL());
      dependencyQuery.ReplaceReferences(comPKgData.PkGItem);
      if (System.IO.File.Exists(element.file)) {
        element.owner.DeleteItem(element);
      }
    }
  }


  /**
   * 查找图片是否在Common包中
   * 有这返回true,以及Common包中的Item
   * 没有这返回false，以及第一个包的Item
   *
   * @param repeatPicItemArray
   * @returns
   */

  public static FindPicItemExistCommonPackage(
    repeatPicItemArray: System.Collections.Generic.List$1<FairyEditor.FPackageItem>
  ): ComPKgData {
    let commPkgData: ComPKgData = new ComPKgData();
    commPkgData.InComPKG = false;
    commPkgData.PkGItem = repeatPicItemArray.get_Item(0);
    commPkgData.NotInComPKGItems = new FPackageItemList();

    for (let i = 0; i < repeatPicItemArray.Count; i++) {
      const element: FairyEditor.FPackageItem = repeatPicItemArray.get_Item(i);
      // console.log(element.owner);
      // console.log(element.file);
      if (element.owner.name === commPkgName) {
        commPkgData.InComPKG = true;
        commPkgData.PkGItem = element;
      } else {
        commPkgData.NotInComPKGItems.Add(element);
      }
    }
    return commPkgData;
  }

  /**
   * 查找图片依赖
   */
  public static GetPicReferences(url: string): FairyEditor.DependencyQuery {
    let dependencyQuery: FairyEditor.DependencyQuery = null;
    if (dependencyQuery === null) {
      dependencyQuery = new FairyEditor.DependencyQuery();
    }
    dependencyQuery.QueryReferences(App.project, url);
    let referenceInfos: System.Collections.Generic.List$1<FairyEditor.ReferenceInfo> =
      dependencyQuery.references;
    console.log("referenceInfos.Count:" + referenceInfos.Count);
    return dependencyQuery;
  }

  /**
   * 得到公共包Res目录
   * @param CommonPKG
   * @returns
   */
  public static GetCommonPKGRes(
    CommonPKG: FairyEditor.FPackage
  ): FairyEditor.FPackageItem {
    let ComPKResItem: FairyEditor.FPackageItem = null;
    for (let j = 0; j < CommonPKG.items.Count; j++) {
      const element = CommonPKG.items.get_Item(j);
      // console.log("el:"+element.name);
      if (element.name === "Res") {
        ComPKResItem = element;
      }
    }
    return ComPKResItem;
  }

  /**
   * 查找包根据名字
   * @returns
   */
  public static GetPKGByName(PKGName: string): FairyEditor.FPackage {
    let commonPKG: FairyEditor.FPackage = null;
    for (let i = 0; i < App.project.allPackages.Count; i++) {
      const element: FairyEditor.FPackage = App.project.allPackages.get_Item(i);
      if (element.name === PKGName) {
        // console.log(element.name);
        commonPKG = element;
      }
    }
    if (commonPKG == null) {
      console.error("名字为" + PKGName + "的包不存在");
    }
    return commonPKG;
  }

  /**
   * 测试计算图片MD5值
   */
  public static testCalMd5(): void {
    let p = App.project.assetsPath;
    let fp = System.IO.Path.Combine(p, "PK1", "Res");
    console.log(fp);

    let files = System.IO.Directory.GetFiles(fp);
    for (let i = 0; i < files.Length; i++) {
      const element = files[i];
      console.log(element);
      System.IO.File.Exists(element)
      {
        let md5str = FairyEditor.BuilderUtil.GetMD5HashFromFile(element);
        console.log(md5str);
      }

    }

    let fp1 = System.IO.Path.Combine(p, "PK1", "Com");
    let files1 = System.IO.Directory.GetFiles(fp1);
    for (let i = 0; i < files1.Length; i++) {
      const element1 = files1[i];
      console.log(element1);

      System.IO.File.Exists(element1)
      {
        let md5str1 = FairyEditor.BuilderUtil.GetMD5HashFromFile(element1);
        console.log(md5str1);
      }

    }
  }

  /**
   *
   * 测试移动资源到公共包
   */
  public static testMovePackItem(): void {
    let CommonPKG = Utils.GetPKGByName(commPkgName);
    let CommonPKGResPath = System.IO.Path.Combine(CommonPKG.basePath, "Res");
    console.log(CommonPKGResPath);
    let PKG1 = Utils.GetPKGByName("PK1");
    console.log(PKG1);
    let id: string = "k3bj1"; //p1.jpg
    let PkGItem: FairyEditor.FPackageItem = PKG1.GetItem(id);
    console.log(PkGItem.name);
    console.log(PkGItem.fileName);
    console.log(PkGItem.path);
    let ComPKResItem: FairyEditor.FPackageItem = null;
    for (let j = 0; j < CommonPKG.items.Count; j++) {
      const element = CommonPKG.items.get_Item(j);
      console.log("el:" + element.name);
      if (element.name === "Res") {
        ComPKResItem = element;
      }
    }

    if (CommonPKG != null) {
      let nwResPath = System.IO.Path.Combine(
        CommonPKGResPath,
        PkGItem.fileName
      );
      console.log(nwResPath);
      let ItemArray: System.Collections.Generic.List$1<FairyEditor.FPackageItem> =
        new FPackageItemList();
      ItemArray.Add(PkGItem);
      let libraryView = new FairyEditor.View.LibraryView();
      libraryView.MoveResources(ComPKResItem, ItemArray);
      // libraryView.MoveResources(CommonPKG.rootItem,ItemArray);//跨包移动无法获取回调
      // PKG1.MoveItem(PkGItem,"/Com/");//本包内移动
    }
  }
}
